#include <hd_led.h>
#include <hd_oled.h>
#include <pd_i2c_hd.h>
#include <hd_oled_protocol_i2c.h>
#include <pd_rtc.h>
#include <delay.h>
#include "main.h"


#define ARRAY_SIZE(x)       sizeof(x) / sizeof(x[0])
#define USE_HARDWARE_SPI    1
#define USE_HARDWARE_I2C    1
OLED oled;

extern void SystemClock_Config(void);

void oled_instance(OLED *oled);

int main(void) {

    SystemClock_Config();

    NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);

    oled_instance(&oled);

    RealTimeClock rtc;
    RealTimeClock_constructor(&rtc);

    uint16_t RTC_datetime[7] = {24, 0x07, 0x25, 0x15, 0x56, 0x59, 0x4};
    RealTimeClock_init(&rtc, RTC_datetime);

    OLED_printf(&oled, 0, 00, "Date:XX-XX-XX");
    OLED_printf(&oled, 0, 16, "Time:XX:XX:XX");
    OLED_printf(&oled, 0, 32, "Time:");
    OLED_printf(&oled, 0, 48, "Date:");
    OLED_refresh(&oled);

    while (1) {
        RealTimeClock_getDatetime(&rtc);

        OLED_printf(&oled, 40, 00, "%02d", RealTimeClock_getYear(&rtc));     // Year
        OLED_printf(&oled, 64, 00, "%02X", RealTimeClock_getMonth(&rtc));    // Month
        OLED_printf(&oled, 88, 00, "%02X", RealTimeClock_getDay(&rtc));      // Day
        OLED_printf(&oled, 40, 16, "%02X", RealTimeClock_getHour(&rtc));     // Hour
        OLED_printf(&oled, 64, 16, "%02X", RealTimeClock_getMinute(&rtc));   // Min
        OLED_printf(&oled, 88, 16, "%02X", RealTimeClock_getSecond(&rtc));   // Second
        OLED_printf(&oled, 112, 0, "%d", RealTimeClock_getWeek(&rtc));       // Week
        OLED_printf(&oled, 40, 32, "%06X", RealTimeClock_getTime(&rtc));     // second counter
        OLED_printf(&oled, 40, 48, "%08X", RealTimeClock_getDate(&rtc));     // date counter
        OLED_refresh(&oled);

        delay_ms(500);
    }

}


void oled_instance(OLED *oled) {
    // I2C gpio init
    static GPIO oledSckGPIO, oledSdaGPIO;
    GPIO_constructor(&oledSckGPIO, GPIOB, LL_GPIO_PIN_10); // I2Cx_SCK
    GPIO_constructor(&oledSdaGPIO, GPIOB, LL_GPIO_PIN_11); // I2Cx_SDA

#ifdef USE_HARDWARE_I2C
    static I2CHardware i2c2;
    I2CHardware_constructor(&i2c2, I2C2, &oledSckGPIO, &oledSdaGPIO);
#elif USE_SIMULATE_I2C
    static I2CSimulate i2c2;
    I2CSimulate_constructor(&i2c2, &oledSckGPIO, &oledSdaGPIO);
#endif
    I2C_init((I2C *) &i2c2);

    // OLED protocol of I2C
    static OLEDProtocolI2C oledProtocolI2c;
    OLEDProtocolI2C_constructor(&oledProtocolI2c, (I2C *) &i2c2);

    // OLED font instance.
    static OLEDFont oledFont;
    OLEDFont_contructor(&oledFont, NULL);

    // OLED instance of 4-PIN(I2C)
    OLED_constructor(oled, (OLEDProtocol *) &oledProtocolI2c, &oledFont);

    OLED_init(oled);

    OLED_clear(oled);
    OLED_refresh(oled);
}

